home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / GX Libraries / TransformLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-31  |  10.0 KB  |  322 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        TransformLibrary.c
  4.  
  5.     Contains:    graphics libraries - operations on transforms
  6.     
  7.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  8.     
  9.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>      1/9/95    JD        changed 'boolean' to 'Boolean'
  14.          <1>      1/9/95    JD        First checked in.
  15. */
  16.  
  17. #include <Memory.h>
  18. #include "GraphicsLibraries.h"
  19.  
  20. gxViewPort GetTransformViewPort(gxTransform xform)
  21. {
  22.     short portCount;
  23.  
  24.     if (xform == nil)
  25.         xform = GXGetShapeTransform(GXGetDefaultShape(gxEmptyType));
  26.     portCount = GXGetTransformViewPorts(xform, nil);
  27.     if (portCount == 0)
  28.         return nil;
  29.     else if (portCount <= 10) { /* use the stack if there's a reasonable number of ports */
  30.         gxViewPort ports[10];
  31.  
  32.         GXGetTransformViewPorts(xform, ports);
  33.         return ports[0];
  34.     } else {                /* else get memory from the heap */
  35.         gxViewPort *ports;
  36.         gxViewPort port;
  37.  
  38.         ports = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort));
  39.         GXGetTransformViewPorts(xform, ports);
  40.         port = ports[0];
  41.         DisposePtr((Ptr) ports);
  42.         return port;
  43.     }
  44. }
  45.  
  46. void SetTransformViewPort(gxTransform xForm, gxViewPort port)
  47. {
  48.     GXSetTransformViewPorts(xForm, 1, &port);
  49. }
  50.  
  51.  
  52. void AddToTransformViewPort(gxTransform xform, gxViewPort newPort)
  53. {
  54.     gxViewPort *ports, *portPtr;
  55.     short portCount, count;
  56.  
  57.     if (xform == nil)
  58.         xform = GXGetShapeTransform(GXGetDefaultShape(gxEmptyType));
  59.     count = portCount = GXGetTransformViewPorts(xform, nil) + 1;
  60.     portPtr = ports = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort));
  61.     GXGetTransformViewPorts(xform, ports);
  62.     while (--count > 0)                /* do nothing if port order is already in transform */
  63.         if (*portPtr++ == newPort) 
  64.             goto disposeTemp;
  65.     *portPtr = newPort;
  66.     GXSetTransformViewPorts(xform, portCount, ports);
  67. disposeTemp:
  68.     DisposePtr((Ptr) ports);
  69. }
  70.  
  71. void SetShapeViewPort(gxShape sh, gxViewPort port)
  72. {
  73.     GXSetShapeViewPorts(sh, 1, &port);
  74. }
  75.  
  76. gxViewPort GetShapeViewPort(gxShape sh)
  77. {
  78.     return GetTransformViewPort(GXGetShapeTransform(sh));
  79. }
  80.  
  81. void SetDeepShapeViewPorts(gxShape sh, long portCount, const gxViewPort portList[])
  82. {
  83.     if (GXGetShapeType(sh) == gxPictureType) {
  84.         register short count = GXGetPicture(sh, nil, nil, nil, nil);
  85.         gxShape itemShape;
  86.         gxTransform itemTransform;
  87.  
  88.         while( count ) {
  89.             GXGetPictureParts(sh, count, 1, &itemShape, nil, nil, &itemTransform);
  90.             if (itemTransform)
  91.                 GXSetTransformViewPorts(itemTransform, portCount, portList);
  92.             SetDeepShapeViewPorts(itemShape, portCount, portList);
  93.             --count;
  94.         }
  95.     } 
  96.     GXSetShapeViewPorts(sh, portCount, portList);
  97. }
  98.  
  99.  
  100. void SetDeepShapeTransform(gxShape sh, gxTransform xform)
  101. {
  102.     if (GXGetShapeType(sh) == gxPictureType) {
  103.         register short count = GXGetPicture(sh, nil, nil, nil, nil);
  104.         gxShape itemShape;
  105.         gxTransform itemTransform;
  106.         
  107.         while (count) {
  108.             GXGetPictureParts(sh, count, 1, &itemShape, nil, nil, &itemTransform);
  109.             if (itemTransform) {
  110.                 gxStyle itemStyle;
  111.                 gxInk itemInk;
  112.                 
  113.                 GXGetPictureParts(sh, count, 1, &itemShape, &itemStyle, &itemInk, &itemTransform);
  114.                 GXSetPictureParts(sh, count, 1, 1, &itemShape, &itemStyle, &itemInk, &itemTransform);
  115.             }
  116.             SetDeepShapeTransform(itemShape, xform);
  117.             count--;
  118.         }
  119.     }
  120.     GXSetShapeTransform(sh, xform);
  121. }
  122.  
  123. void SetDeepShapeViewPort(gxShape sh, gxViewPort newPort)
  124. {
  125.     SetDeepShapeViewPorts(sh, 1, &newPort);
  126. }
  127.  
  128. void PreMapTransform(gxTransform source, gxMapping *map)
  129. {
  130.     gxMapping copy, xform;
  131.  
  132.     CopyToMapping(©, map);
  133.     GXGetTransformMapping(source, &xform);
  134.     MapMapping(©, &xform);
  135.     GXSetTransformMapping(source, ©);
  136. }
  137.  
  138. #ifdef debugging
  139. static void ClearBytes(char *block, long length)
  140. {
  141.     while (--length >= 0)
  142.         *block++ = 0;
  143. }
  144. #endif
  145.  
  146. /*    Set each of the default shapes' transforms to have only the gxViewPort in their gxViewPort list.
  147.     Default shapes that shared a gxTransform with each other will still share it; those with unique
  148.     gxTransform will still have unique ones.  Default shapes that shared a gxTransform with a non-
  149.     default gxShape will do so no longer:  only the default shapes have their gxTransform changed.  */
  150. void SetDefaultViewPort(gxViewPort port)
  151. {
  152.     /*    xforms contains the gxTransform for each gxShape, or nil if the gxShape shares a gxTransform
  153.         with another default gxShape.  owners contains the number of default shapes that own
  154.         the gxTransform.  offset contains the index of the gxShape's gxTransform in the xforms array,
  155.         if the gxShape share's a gxTransform with an earlier gxShape.  copied is true for transforms
  156.         that were created in this routine, and hence need to be disposed here.
  157.         
  158.         An index of zero means the default gxTransform.  owners and offsets could be folded into the
  159.         same array, as owners is only used where xforms is non-nil, and offsets where it is nil.
  160.     */
  161.     gxTransform xforms[gxPictureType + 1];
  162.     short owners[gxPictureType + 1];
  163.     short offsets[gxPictureType + 1];
  164.     Boolean copied[gxPictureType + 1];
  165.     short i, j;
  166.  
  167. /* the following lines are desirable when debugging with memory flipping enabled */
  168. #ifdef debugging    
  169.     ClearBytes((char *) xforms, sizeof(xforms));
  170.     ClearBytes((char *) owners, sizeof(owners));
  171.     ClearBytes((char *) offsets, sizeof(offsets));
  172.     ClearBytes((char *) copied, sizeof(copied));
  173. #endif
  174.     /* collect the transforms into the arrays */
  175.     for (i = gxEmptyType; i <= gxPictureType; i++) {
  176.         xforms[i] = GXGetShapeTransform(GXGetDefaultShape(i));
  177.         owners[i] = 1;
  178.         copied[i] = false;
  179.             
  180.         for (j = gxEmptyType; j < i; j++)
  181.             if (xforms[i] == xforms[j]) {
  182.                 xforms[i] = nil;
  183.                 offsets[i] = j;
  184.                 owners[j]++;
  185.                 break;
  186.             }
  187.     }
  188.     
  189.     /* make copies of the transforms, where necessary */
  190.     for (i = gxEmptyType; i <= gxPictureType; i++) {
  191.         gxTransform xform = xforms[i];
  192.         gxViewPort oldPort;
  193.         
  194.         if (xform == nil) continue;
  195.         
  196.         /* maybe the transform already has the right port */
  197.         if (GXGetTransformViewPorts(xform, nil) == 1 && (GXGetTransformViewPorts(xform, &oldPort), oldPort) == port)
  198.             continue;
  199.         if (GXGetTransformOwners(xform) != owners[i]) {
  200.             /* some of the owners aren't default shapes */
  201.             xforms[i] = xform = GXCopyToTransform(nil, xform);
  202.             copied[i] = true;
  203.         }
  204.         GXSetTransformViewPorts(xform, 1, &port);
  205.     }
  206.     
  207. #ifdef debugging    
  208.     GXIgnoreGraphicsNotice(transform_already_set);
  209. #endif
  210.     for (i = gxEmptyType; i <= gxPictureType; i++) {
  211.         gxTransform xform = xforms[i];
  212.         
  213.         GXSetShapeTransform(GXGetDefaultShape(i), xform ? xform : xforms[offsets[i]]);
  214.         if (copied[i])
  215.             GXDisposeTransform(xform);
  216.     }
  217. #ifdef debugging    
  218.     GXPopGraphicsNotice();
  219. #endif
  220. #undef defaultType
  221. }
  222.  
  223. gxViewGroup CopyViewGroup(gxViewGroup group)
  224. {
  225.     /* create a new view group */
  226.     gxViewGroup newGroup = GXNewViewGroup();
  227.  
  228.     /* copy the view device list */
  229.     {    long deviceCount = GXGetViewGroupViewDevices(group, nil), count = deviceCount;
  230.         gxViewDevice *deviceList = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice)), *list = deviceList;
  231.         GXGetViewGroupViewDevices(group, deviceList);
  232.         while (count--)
  233.         {    GXSetViewDeviceViewGroup(*list = GXCopyToViewDevice(nil, *list), newGroup);
  234.             list++;
  235.         }
  236.         DisposePtr((Ptr) deviceList);
  237.     }
  238.  
  239.     /* copy the view port list */
  240.     {    long portCount = GXGetViewGroupViewPorts(group, nil), count = portCount;
  241.         gxViewPort *oldPortList = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort)), *oldList = oldPortList;
  242.         gxViewPort *newPortList = (gxViewPort *) NewPtr(portCount * sizeof(gxViewPort)), *newList = newPortList;
  243.         GXGetViewGroupViewPorts(group, oldPortList);
  244.         while (count--)
  245.             GXSetViewPortViewGroup(*newList++ = GXCopyToViewPort(nil, *oldList++), newGroup);
  246.  
  247.     /* copy the view port hierarchy */
  248.         oldList = oldPortList; newList = newPortList;
  249.         for (count = portCount; count--; newList++)
  250.         {    gxViewPort parent = GXGetViewPortParent(*oldList++);
  251.             if (parent)
  252.             {    gxViewPort *optr = oldPortList, *nptr = newPortList;
  253.                 long pcnt = portCount;
  254.                 Boolean match = false;
  255.                 while (pcnt-- && !(match = *optr == parent)) { optr++; nptr++; }
  256.                 if (match) GXSetViewPortParent(*newList, *nptr);
  257.             }
  258.         }
  259.         DisposePtr((Ptr) newPortList);
  260.         DisposePtr((Ptr) oldPortList);
  261.     }
  262.     return newGroup;
  263. }
  264.  
  265. /* the newGroup should have at least as many viewPorts in it as the oldGroup */
  266. /* ideally, newGroup and oldGroup should be copies of each other */
  267. gxTransform ChangeTransformViewGroup(gxTransform xform, gxViewGroup oldGroup, gxViewGroup newGroup)
  268. {
  269.     long oldPortCount = GXGetViewGroupViewPorts(oldGroup, nil);
  270.     long newPortCount = GXGetViewGroupViewPorts(newGroup, nil);
  271.     long xformPortCount = GXGetTransformViewPorts(xform, nil);
  272.     gxViewPort *oldPortList = (gxViewPort *) NewPtr(oldPortCount * sizeof(gxViewPort));
  273.     gxViewPort *newPortList = (gxViewPort *) NewPtr(newPortCount * sizeof(gxViewPort));
  274.     gxViewPort *xformPortList = (gxViewPort *) NewPtr(xformPortCount * sizeof(gxViewPort));
  275.     GXGetViewGroupViewPorts(oldGroup, oldPortList);
  276.     GXGetViewGroupViewPorts(newGroup, newPortList);
  277.     GXGetTransformViewPorts(xform, xformPortList);
  278.     {    long xcnt = xformPortCount;
  279.         gxViewPort *xptr = xformPortList;
  280.         while (xcnt--)
  281.         {    gxViewPort order = *xptr, *optr = oldPortList, *nptr = newPortList;
  282.             long pcnt = oldPortCount;
  283.             Boolean match = false;
  284.             while (pcnt-- && !(match = *optr == order)) { optr++; nptr++; }
  285.             if (match) *xptr = *nptr;
  286.             xptr++;
  287.         }
  288.     }
  289.     GXSetTransformViewPorts(xform, xformPortCount, xformPortList);
  290.     DisposePtr((Ptr) xformPortList);
  291.     DisposePtr((Ptr) newPortList);
  292.     DisposePtr((Ptr) oldPortList);
  293.     return xform;
  294. }
  295.  
  296. gxShape ChangeShapeViewGroup(gxShape source, gxViewGroup oldGroup, gxViewGroup newGroup)
  297. {
  298.     gxTransform xform = GXGetShapeTransform(source);
  299.     if (GXGetTransformOwners(xform) > 1)            /* is it shared? */
  300.     {    xform = GXCopyToTransform(nil, xform);
  301.         GXSetShapeTransform(source, xform);
  302.         GXDisposeTransform(xform);
  303.     }
  304.     ChangeTransformViewGroup(xform, oldGroup, newGroup);
  305.     return source;
  306. }
  307.  
  308. gxTransform SeparateShapeTransform(gxShape source)
  309. {
  310.     gxTransform old = GXCloneTransform(GXGetShapeTransform(source)), xnew = GXCopyToTransform(nil, old);
  311.     GXSetShapeTransform(source, xnew);
  312.     GXDisposeTransform(xnew);
  313.     return old;
  314. }
  315.  
  316. void ReuniteShapeTransform(gxShape target, gxTransform separate)
  317. {
  318.     GXSetShapeTransform(target, separate);
  319.     GXDisposeTransform(separate);
  320.     return;
  321. }
  322.